package main

import (
	"context"
	"fmt"
	"math/rand"
	"runtime"
	"time"

	pool "goroutine-pool"
)

func main() {
	fmt.Printf("=== Goroutine Pool 示例 ===\n")
	fmt.Printf("系统CPU核心数: %d\n\n", runtime.NumCPU())

	// === 示例1: 使用带每个CPU核心最大协程数限制的协程池 ===
	fmt.Println("\n===== 示例1: 每个CPU核心最大协程数限制 =====")
	exampleWithMaxPerCore()

	// === 示例2: 无限制的协程池 ===
	fmt.Println("\n===== 示例2: 无限制协程池 =====")
	exampleWithoutLimit()
}

func exampleWithMaxPerCore() {
	// 创建协程池，每个CPU核心最大承载3个协程
	p := pool.NewPoolWithMaxPerCore(100, 3)

	// 创建多个任务
	tasks := []*pool.Task{
		// 任务1: 高优先级，绑定到CPU 0
		{
			Name: "高优先级任务-CPU0",
			Fn: func(ctx context.Context) error {
				fmt.Printf("[TASK] 高优先级任务开始执行（绑定到CPU 0）\n")
				time.Sleep(2 * time.Second)
				fmt.Printf("[TASK] 高优先级任务完成\n")
				return nil
			},
			Config: pool.TaskConfig{
				CPUCore:  0,
				Priority: pool.PriorityHigh,
				Timeout:  5 * time.Second,
			},
		},

		// 任务2: 普通优先级，绑定到CPU 1
		{
			Name: "普通优先级任务-CPU1",
			Fn: func(ctx context.Context) error {
				fmt.Printf("[TASK] 普通优先级任务开始执行（绑定到CPU 1）\n")
				time.Sleep(3 * time.Second)
				fmt.Printf("[TASK] 普通优先级任务完成\n")
				return nil
			},
			Config: pool.TaskConfig{
				CPUCore:  1 % runtime.NumCPU(),
				Priority: pool.PriorityNormal,
				Timeout:  10 * time.Second,
			},
		},

		// 任务3: 低优先级，不指定CPU
		{
			Name: "低优先级任务",
			Fn: func(ctx context.Context) error {
				fmt.Printf("[TASK] 低优先级任务开始执行（不绑定CPU）\n")
				time.Sleep(1 * time.Second)
				fmt.Printf("[TASK] 低优先级任务完成\n")
				return nil
			},
			Config: pool.TaskConfig{
				CPUCore:  -1, // 不指定CPU
				Priority: pool.PriorityLow,
				Timeout:  0, // 无时间限制
			},
		},

		// 任务4: 超时任务（演示超时功能）
		{
			Name: "超时任务",
			Fn: func(ctx context.Context) error {
				fmt.Printf("[TASK] 超时任务开始执行（将在2秒后超时）\n")
				select {
				case <-time.After(5 * time.Second):
					fmt.Printf("[TASK] 超时任务正常完成\n")
					return nil
				case <-ctx.Done():
					fmt.Printf("[TASK] 超时任务被取消\n")
					return ctx.Err()
				}
			},
			Config: pool.TaskConfig{
				CPUCore:  -1,
				Priority: pool.PriorityNormal,
				Timeout:  2 * time.Second, // 2秒超时
			},
		},

		// 任务5: 返回错误的任务
		{
			Name: "错误任务",
			Fn: func(ctx context.Context) error {
				fmt.Printf("[TASK] 错误任务开始执行\n")
				time.Sleep(1 * time.Second)
				return fmt.Errorf("模拟任务错误")
			},
			Config: pool.TaskConfig{
				CPUCore:  -1,
				Priority: pool.PriorityNormal,
				Timeout:  5 * time.Second,
			},
		},
	}

	// 批量提交任务
	fmt.Println(">>> 批量提交5个任务")
	p.SubmitMultiple(tasks)

	// 等待3秒后再提交更多任务
	time.Sleep(3 * time.Second)

	// 动态添加更多任务
	fmt.Println("\n>>> 动态添加更多任务")
	for i := 0; i < 5; i++ {
		taskNum := i
		p.Submit(&pool.Task{
			Name: fmt.Sprintf("动态任务-%d", taskNum),
			Fn: func(ctx context.Context) error {
				duration := time.Duration(rand.Intn(3)+1) * time.Second
				fmt.Printf("[TASK] 动态任务-%d 开始执行，将运行 %v\n", taskNum, duration)
				time.Sleep(duration)
				return nil
			},
			Config: pool.TaskConfig{
				CPUCore:  -1,
				Priority: pool.Priority(rand.Intn(3)), // 随机优先级
				Timeout:  10 * time.Second,
			},
		})
	}

	// 等待所有任务完成
	fmt.Println("\n>>> 等待所有任务完成...")
	p.Wait()

	// 显示最终统计信息
	fmt.Println("\n=== 最终统计信息 ===")
	fmt.Printf("运行中协程数: %d\n", p.GetRunningCount())
	fmt.Printf("成功完成任务数: %d\n", p.GetSuccessCount())
	fmt.Printf("失败任务数: %d\n", p.GetFailedCount())
	fmt.Printf("总完成数: %d\n", p.GetTotalCompletedCount())
	fmt.Println("\n=== 示例1完成 ===")
}

func exampleWithoutLimit() {
	// 创建无限制的协程池
	p := pool.NewPool(100)

	// 创建多个任务
	tasks := []*pool.Task{
		// 任务1: 绑定到CPU 0
		{
			Name: "无限制-CPU0",
			Fn: func(ctx context.Context) error {
				fmt.Printf("[TASK] 无限制任务开始执行（绑定到CPU 0）\n")
				time.Sleep(2 * time.Second)
				fmt.Printf("[TASK] 无限制任务完成\n")
				return nil
			},
			Config: pool.TaskConfig{
				CPUCore:  0,
				Priority: pool.PriorityNormal,
				Timeout:  5 * time.Second,
			},
		},
	}

	// 提交任务
	fmt.Println(">>> 提交1个任务")
	p.SubmitMultiple(tasks)

	// 动态添加更多任务
	fmt.Println("\n>>> 动态添加更多任务")
	for i := 0; i < 5; i++ {
		taskNum := i
		p.Submit(&pool.Task{
			Name: fmt.Sprintf("无限制-动态任务-%d", taskNum),
			Fn: func(ctx context.Context) error {
				duration := time.Duration(rand.Intn(3)+1) * time.Second
				fmt.Printf("[TASK] 无限制动态任务-%d 开始执行，将运行 %v\n", taskNum, duration)
				time.Sleep(duration)
				return nil
			},
			Config: pool.TaskConfig{
				CPUCore:  -1,
				Priority: pool.Priority(rand.Intn(3)),
				Timeout:  10 * time.Second,
			},
		})
	}

	// 等待所有任务完成
	fmt.Println("\n>>> 等待所有任务完成...")
	p.Wait()

	// 显示最终统计信息
	fmt.Println("\n=== 最终统计信息 ===")
	fmt.Printf("运行中协程数: %d\n", p.GetRunningCount())
	fmt.Printf("成功完成任务数: %d\n", p.GetSuccessCount())
	fmt.Printf("失败任务数: %d\n", p.GetFailedCount())
	fmt.Printf("总完成数: %d\n", p.GetTotalCompletedCount())
	fmt.Println("\n=== 示例2完成 ===")
}
